package com.zlf;

import com.zlf.realm.CustomerMD5Realm;
import com.zlf.realm.CustomerRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;

/**
 * @ClassName ShiroAuthenticatorTest
 * @Description 认证的实现
 * @Author zlf
 * @Date 2021/5/24 9:18
 */
public class ShiroAuthenticatorTest {

    public static void main(String[] args) {
//        ShiroAuthenticatorTest.demo();
//        ShiroAuthenticatorTest.customerRealm();
//        ShiroAuthenticatorTest.MD5Demo();
        ShiroAuthenticatorTest.customerMd5Realm();
    }

    /*
    初体验
     */
    private static void demo() {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken admin = new UsernamePasswordToken("admin", "123456");
        try {
            System.out.println("认证状态：" + subject.isAuthenticated());
            subject.login(admin);
            System.out.println("认证状态：" + subject.isAuthenticated());
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败：用户不存在！");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败：密码不正确！");
        } catch (DisabledAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败：账号被禁用！");
        } catch (ExcessiveAttemptsException e) {
            e.printStackTrace();
            System.out.println("认证失败：登录失败次数过多！");
        } catch (ExpiredCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败：凭证过期！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
    自定义Realm
     */
    private static void customerRealm() {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        securityManager.setRealm(new CustomerRealm());
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken admin = new UsernamePasswordToken("admin", "123456");
        try {
            System.out.println("认证状态：" + subject.isAuthenticated());
            subject.login(admin);
            System.out.println("认证状态：" + subject.isAuthenticated());
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败：用户不存在！");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败：密码不正确！");
        } catch (DisabledAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败：账号被禁用！");
        } catch (ExcessiveAttemptsException e) {
            e.printStackTrace();
            System.out.println("认证失败：登录失败次数过多！");
        } catch (ExpiredCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败：凭证过期！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
    md5加密
     */
    private static void MD5Demo() {
        // MD5加密，无随机盐，无散列
        Md5Hash md5Hash01 = new Md5Hash("123456");
        System.out.println(md5Hash01.toHex());

        // MD5+随机盐加密，无散列
        Md5Hash md5Hash02 = new Md5Hash("123456", "aabbcc");
        System.out.println(md5Hash02.toHex());

        // MD5+随机盐加密+散列1024
        Md5Hash md5Hash03 = new Md5Hash("123456", "aabbcc", 1024);
        System.out.println(md5Hash03.toHex());
    }

    /*
    自定义加密Realm
     */
    private static void customerMd5Realm() {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        CustomerMD5Realm realm = new CustomerMD5Realm();
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); // 为realm设置凭证匹配器
        credentialsMatcher.setHashAlgorithmName("md5"); // 设置加密算法名称
        credentialsMatcher.setHashIterations(1024); // 设置hash次数
        realm.setCredentialsMatcher(credentialsMatcher);
        securityManager.setRealm(realm);
        SecurityUtils.setSecurityManager(securityManager);
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken admin = new UsernamePasswordToken("admin", "123456");
        try {
            System.out.println("认证状态：" + subject.isAuthenticated());
            subject.login(admin);
            System.out.println("认证状态：" + subject.isAuthenticated());
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败：用户不存在！");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败：密码不正确！");
        } catch (DisabledAccountException e) {
            e.printStackTrace();
            System.out.println("认证失败：账号被禁用！");
        } catch (ExcessiveAttemptsException e) {
            e.printStackTrace();
            System.out.println("认证失败：登录失败次数过多！");
        } catch (ExpiredCredentialsException e) {
            e.printStackTrace();
            System.out.println("认证失败：凭证过期！");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
